using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace usm.SolDev.Common
{
    public static class Cryptography
    {
        #region RSA Alghorithm

        #region 1024 bits keys for RSA alghoritm
        private static readonly string PUBLIC_RSA_KEY = "<RSAKeyValue><Modulus>tsO2wN3qzltikwIQlwdktfkqbLOL5i9d2ntwpBqKL4kE+w5QpkJEXHN7gGLeoDZDyl0i7SHJnqRr3Y8+1wAj86f5gXVUxo0PABQqT6OuHYL4SAdvzVxDZ6PdGC9gX+rkwIQasn0VQMHIQqt4egjby7AM+Y4wvvcqgpL8vjXMYGU=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
        private static readonly string PRIVATE_RSA_KEY = "<RSAKeyValue><Modulus>tsO2wN3qzltikwIQlwdktfkqbLOL5i9d2ntwpBqKL4kE+w5QpkJEXHN7gGLeoDZDyl0i7SHJnqRr3Y8+1wAj86f5gXVUxo0PABQqT6OuHYL4SAdvzVxDZ6PdGC9gX+rkwIQasn0VQMHIQqt4egjby7AM+Y4wvvcqgpL8vjXMYGU=</Modulus><Exponent>AQAB</Exponent><P>6IwLq0ONyrA1+NbApt117Eo1kwSDAaDowTxMzuvn/Xh1kVF1bsR+sj21BzFjry3f2kq3SkCEAx1cGPJHvqoYEw==</P><Q>yTJe76aqSyTbb/6vQqB4JRti1TvXfxG1r+svCyscQULPbuyLaeA3nMN39sTKTBgpt8FoD6K0A37YS2/SRzwkpw==</Q><DP>lpSgtbyfoyDpQgGlbCe5RVFkUZe5USOltALc5Zxic4I99uRde2VnePl2MHstxnCZJFv/Rehy0yV+znSMOo0f2w==</DP><DQ>HAwZj+777l3E+WfXpsIX/ZRDwtYExIIDgfKXLEdmOPLHV/9BsBDBr+jP4GaujM0Rg7xCdWuJDLOyE1ITTjrkIQ==</DQ><InverseQ>JA9TSMeqMGf6B7fYVZFlxSHdioXngRe+FtlK7IY5z4eYpcJH/XHdmCRDuCXXclHETWIfIfkP7cVaQDwWrLHpqA==</InverseQ><D>Ir9bA5gtiEY/m4uM8+nn7+ELe9c3BfCDe4J0i/6vvxHh7IlwM+vta1ZZaLNjeDpY8SR7+3GtD4hbKaiOXfoc22fhHBsynxtz3Diezlprxtlk9hbhwoiUImyNssdURyWYTW9oii2lZ+0ihLCUUTlT+7AQoWvIQZuCssKRjB2/N5E=</D></RSAKeyValue>";
        #endregion

        /// <summary>
        ///     Decrypt string with RSA algorithm
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string DecryptRSA(string str)
        {
            byte[] dataToDecrypt = System.Convert.FromBase64String(str);

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(PRIVATE_RSA_KEY);
            return System.Text.ASCIIEncoding.ASCII.GetString(rsa.Decrypt(dataToDecrypt, false));
        }

        /// <summary>
        /// gets encrypted string with RSA algorithm
        /// </summary>
        /// <param name="str">input string</param>
        /// <returns>Encrypted string</returns>
        public static string CryptRSA(string str)
        {
            byte[] dataToEncrypt = System.Text.ASCIIEncoding.ASCII.GetBytes(str);

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(PUBLIC_RSA_KEY);
            return System.Convert.ToBase64String(rsa.Encrypt(dataToEncrypt, false));
        }
        #endregion

        #region SHA246 Alghorithm
        /// <summary>
        /// Gets a hashed, with SHA256 algorithm, string
        /// </summary>
        /// <param name="str">The string value to hash</param>
        /// <returns>Hashed string</returns>
        public static string ComputeHashWithSHA256(string str)
        {
            byte[] oBuff = System.Text.Encoding.Unicode.GetBytes(str);
            byte[] hBuff = new System.Security.Cryptography.SHA256Managed().ComputeHash(oBuff);

            return Convert.ToBase64String(hBuff);
        }
        #endregion

        #region Base 64 Code/Decode

        /// <summary>
        ///     Encode a string to base 64
        /// </summary>
        /// <param name="buffer">the string to encode</param>
        /// <returns>the encoded string</returns>
        public static string Base64Encode (string buffer)
        {
            if (buffer == null)
            {
                return null;
            }

            try
            {
                byte[] encData_byte = new byte[buffer.Length];
                encData_byte = System.Text.Encoding.UTF8.GetBytes(buffer);
                string encodedData = Convert.ToBase64String(encData_byte);
                return encodedData;
            }
            catch(Exception ex)
            {
                throw new SolDevException("Error in base64Encode", ex);
            }

        }

        /// <summary>
        ///     Decode a string from base 64 
        /// </summary>
        /// <param name="buffer">encoded buffer</param>
        /// <returns>the decoded string</returns>
        public static string Base64Decode(string buffer)
        {
            if (buffer == null)
            {
                return null;
            }

            try
            {
                System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
                System.Text.Decoder utf8Decode = encoder.GetDecoder();

                byte[] todecode_byte = Convert.FromBase64String(buffer);
                int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
                char[] decoded_char = new char[charCount];

                utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
                string result = new String(decoded_char);
                return result;
            }
            catch (Exception ex)
            {
                throw new SolDevException("Error in base64Decode", ex);
            }
        }

        #endregion

    }
}
